package de.uni_mannheim.informatik.ai.dame_ai.dame.ui;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.Arrays;

import javax.swing.JLayeredPane;

import de.uni_mannheim.informatik.ai.dame_ai.dame.domain.Piece;


public class BoardComponent extends BitmapComponent {
	protected Rectangle2D[] fields = new Rectangle2D[64];
	protected boolean[] highlightedFields = new boolean[64];
	AffineTransform at = new AffineTransform();
	protected Color transparent = new Color(0, 0, 0, 0);
	protected Color blue = new Color(255, 255, 255, 40);
	DameGui listener;
	BufferedImage black;
	BufferedImage blackDame;
	BufferedImage white;
	BufferedImage whiteDame;
	protected short[] pieceStatus= new short[64];
	/**
	 * Create new BoardComponent
	 * @param background The background image
	 * @param r The Bounds of the canvas
	 * @param listener The Jpanel listening to the panel
	 */
	public BoardComponent(BufferedImage background, Rectangle r,DameGui listener) {
		super(background, r);
		createOverlayGrid();
		this.listener = listener;
		addMouseListener(new MyMouseListener());
		// TODO Auto-generated constructor stub
	}
	/**
	 * Insert the images for the pieces
	 * @param pieces The images for the pieces
	 */
	public void insertPieceImages(BufferedImage[] pieces){
		this.black=pieces[Piece.BLACK];
		this.blackDame=pieces[Piece.BLACKDAME];
		this.white=pieces[Piece.WHITE];
		this.whiteDame=pieces[Piece.WHITEDAME];
	}
	/**
	 * Paint pieces onto the background image
	 * @param g2 Graphics element
	 */
	private void paintPieces(Graphics2D g2){
		double fieldSize = bounds.height/(double)8;
		double offset = fieldSize / 4;
		BufferedImage temp;
		for(int i=0; i<8;i++){
			for(int j=0; j<8;j++){
				switch(pieceStatus[i*8+j]){
				case(Piece.BLACK): temp = black;break;
				case(Piece.WHITE): temp = white;break;
				case(Piece.BLACKDAME): temp = blackDame;break;
				case(Piece.WHITEDAME): temp = whiteDame;break;
				default: temp = null;break;
				}
				if(temp!=null){
					g2.drawImage(temp, (int)Math.ceil(j*fieldSize+offset/2),(int)Math.ceil(i*fieldSize+offset/2),(int)Math.ceil(fieldSize-offset),(int)Math.ceil(fieldSize-offset),this);
				}
			}
		}
	}

	/**
	 * Create the Fields ontop of the Grid
	 */
	private void createOverlayGrid() {
		double size = bounds.height / (double)8;
		int startX = 0;
		int startY = 0;
		for (int i = 0; i < 8; i++) {
			for (int j = 0; j < 8; j++) {
				fields[i * 8 + j] = new Rectangle2D.Double(size * j, size * i,
						size, size);
			}
		}
	}

	@Override
	public void paint(Graphics g) {
		super.paint(g);
		createOverlayGrid();
		paintBoard((Graphics2D) g);
		
		System.out.println("Painted Board");
		paintPieces((Graphics2D) g);
	}

	public void paintBoard(Graphics2D g2) {
		for (int i = 0; i < 64; i++) {
			if (highlightedFields[i])
				g2.setPaint(blue);
			else
				g2.setPaint(transparent);
			g2.draw(at.createTransformedShape(fields[i]));
			g2.fill(at.createTransformedShape(fields[i]));
		}

	}

	private void repaint(Rectangle r){
		repaint(r.x,r.y,r.width,r.height);
	}
	public void setHighlightedFields(boolean[] selectedFields) {
		if (!Arrays.equals(highlightedFields, selectedFields)) {
			boolean[] oldFields = highlightedFields;
			this.highlightedFields = selectedFields;
			for(int i = 0; i<highlightedFields.length;i++){
				if(oldFields[i]!=highlightedFields[i]){
					repaint(fields[i].getBounds());
				}
			}
			//repaint();
		}
	}
	public void setPieceStatus(short[] pieceStatus) {
		if(!Arrays.equals(this.pieceStatus,pieceStatus )){
			short[] oldPieces = this.pieceStatus;
			this.pieceStatus = pieceStatus;
			
			for(int i = 0; i<highlightedFields.length;i++){
				if(oldPieces[i]!=this.pieceStatus[i]){
					repaint(fields[i].getBounds());
				}
			}
			//repaint();
		}
	}
	/**
	 * Get the array index of the mouse event
	 * @param p Mouse position
	 * @return The index of game status
	 */
	public int getPosition(Point p) {
		int[] result = new int[2];
		Shape shape;
		for (int i = 0; i < 64; i++) {
			shape = at.createTransformedShape(fields[i]);
			if (shape.contains(p)) {
				return i;
			}
		}
		return -1;
	}
	class MyMouseListener extends MouseAdapter {

		/**
		 * what happens wenn mouse is clicked
		 */
		public void mousePressed(MouseEvent event) {
			Point p = event.getPoint();
			System.out.println("Trying to get Position: " + p);
			int position = getPosition(p);
			System.out.println("Position: "+position);
			if(position!=-1)listener.handleBoardEvent(position);
		}	
	}
}
